import { Component, Node, Animation, AnimationClip, tween, Tween, Sprite, Color, Vec3, _decorator, UITransform, SpriteFrame, resources, Label, instantiate, AnimationState } from 'cc';
import { ResourceLoadManager,SpriteAtlasPath } from '../render/ResourceLoadManager';
import { PlayerType, EntityType, UnitType } from '../../../battle/Enums';
import { TiledObject } from '../render/TiledObject';
import { LOG } from '../../../ConsoleLogCtrl';

const { ccclass, property } = _decorator;

/**
 * 移动方向枚举
 */
export enum MoveDirection {
    /** 向下 */
    DOWN = 'down',
    /** 向左 */
    LEFT = 'left',
    /** 向右 */
    RIGHT = 'right',
    /** 向上 */
    UP = 'up'
}

/**
 * TiledObject动画管理器
 * 负责管理TiledObject的所有动画播放功能
 */
@ccclass('TiledObjectAnimationManager')
export class TiledObjectAnimationManager {
    /** 目标节点 */
    private targetNode: Node;

    /** 实体类型 */
    private entityType: EntityType;

    /** 单位类型 */
    private uType: any;

    /** 玩家类型 */
    private playerType: PlayerType;

    /** 当前移动方向 */
    private currentDirection: MoveDirection = MoveDirection.DOWN;

    /** 是否正在移动 */
    private isMoving: boolean = false;

    /** 动画组件 */
    private animationComponent: Animation | null = null;

    /** 当前播放的动画名称 */
    private currentAnimationName: string | null = null;

    /** 移动tween动画实例 */
    private moveTween: Tween<Node> | null = null;

    /** 受伤/治疗tween动画实例 */
    private injuredTween: Tween<Sprite> | null = null;

    /** 动画切换防抖定时器 */
    private animationSwitchTimer: number | null = null;

    /** 上一次播放的动画名称，用于避免重复播放 */
    private lastPlayedAnimationName: string | null = null;

    /** 箭矢飞行动画实例 */
    private arrowTween: Tween<Node> | null = null;

    /** 箭矢节点实例 */
    private arrowNode: Node | null = null;

    /** 飘字动画实例 */
    private floatingTextTween: Tween<Node> | null = null;

    /** 飘字节点实例 */
    private floatingTextNode: Node | null = null;

    /** tiledObject */
    private tiledObject: TiledObject;

    /**
     * 构造函数
     * @param targetNode 目标节点
     * @param uType 单位类型
     * @param playerType 玩家类型
     * @param entityType 实体类型
     */
    constructor(targetNode: Node, uType: any, playerType: PlayerType, entityType: EntityType) {
        if (!targetNode || !targetNode.isValid) {
            throw new Error('TiledObjectAnimationManager: targetNode无效');
        }
        
        this.targetNode = targetNode;
        this.uType = uType;
        this.playerType = playerType;
        this.entityType = entityType;
        
        // 获取TiledObject组件，如果获取失败则抛出错误
        this.tiledObject = targetNode.getComponent(TiledObject);
        if (!this.tiledObject) {
            LOG.warn('TiledObjectAnimationManager: 无法获取TiledObject组件');
        }
        
        // 初始化动画组件
        this.initializeAnimation();
    }

    /**
     * 初始化动画组件
     */
    private initializeAnimation(): void {
        // 获取或添加Animation组件
        this.animationComponent = this.targetNode.getComponent(Animation);
        if (!this.animationComponent) {
            this.animationComponent = this.targetNode.addComponent(Animation);
        }

        // 确保动画组件正确初始化
        if (this.animationComponent) {
            // 设置默认播放模式
            this.animationComponent.playOnLoad = false;
        }
    }

    /**
     * 播放移动动画
     * 根据移动方向播放对应的动画，使用动画名称匹配
     * @param direction 移动方向，如果不提供则播放默认动画
     */
    public playMoveAnimation(direction?: MoveDirection): void {
        if (!this.animationComponent) {
            LOG.warn('TiledObjectAnimationManager: 动画组件未初始化');
            return;
        }

        // 获取所有可用的动画剪辑
        const clips = this.animationComponent.clips;
        if (clips.length === 0) {
            LOG.warn('TiledObjectAnimationManager: 没有可用的动画剪辑');
            return;
        }

        let targetAnimationName: string | null = null;

        // 根据方向生成目标动画名称
        if (direction) {
            targetAnimationName = this.getDirectionIndex(direction);
        }

        // 根据动画名称查找对应的动画剪辑
        let targetClip = null;
        if (targetAnimationName) {
            targetClip = clips.find(clip => clip.name === targetAnimationName);
        }

        // 如果没有找到指定名称的动画，使用第一个可用动画作为默认
        if (!targetClip) {
            targetClip = clips[0];
            targetAnimationName = targetClip.name;
            LOG.warn(`TiledObjectAnimationManager: 未找到动画 ${direction ? `${this.getDirectionIndex(direction)}` : '指定动画'}，使用默认动画 ${targetAnimationName}`);
        }

        if (targetClip && targetAnimationName) {
            // 如果当前已经在播放这个动画，则不重复播放
            if (this.currentAnimationName === targetAnimationName && this.animationComponent.getState(targetAnimationName)?.isPlaying) {
                return;
            }

            // 如果有其他动画在播放，进行平滑切换
            if (this.currentAnimationName && this.currentAnimationName !== targetAnimationName) {
                const currentState = this.animationComponent.getState(this.currentAnimationName);
                if (currentState && currentState.isPlaying) {
                    // 设置当前动画为正常模式，让它自然结束当前循环
                    currentState.wrapMode = AnimationClip.WrapMode.Normal;
                    // 等待当前动画循环结束后再播放新动画
                    setTimeout(() => {
                        if (this.animationComponent && this.targetNode.isValid) {
                            this.animationComponent.play(targetAnimationName);
                            const newAnimState = this.animationComponent.getState(targetAnimationName);
                            if (newAnimState) {
                                newAnimState.speed = 2.0;
                                newAnimState.wrapMode = AnimationClip.WrapMode.Loop;
                            }
                        }
                    }, 50); // 延迟50ms
                    this.currentAnimationName = targetAnimationName;
                    return;
                }
            }

            // 设置新的动画名称
            this.currentAnimationName = targetAnimationName;

            // 播放新动画
            this.animationComponent.play(targetAnimationName);

            // 设置播放速度为2倍速并启用循环播放
            const animState = this.animationComponent.getState(targetAnimationName);
            if (animState) {
                animState.speed = 2.0;
                animState.wrapMode = AnimationClip.WrapMode.Loop;
            }
        }
    }

    /**
     * 停止移动动画
     */
    public stopMoveAnimation(): void {
        if (!this.animationComponent) {
            return;
        }

        // 清除动画切换定时器
        if (this.animationSwitchTimer !== null) {
            clearTimeout(this.animationSwitchTimer);
            this.animationSwitchTimer = null;
        }

        if (this.currentAnimationName) {
            // 重置循环播放状态为Normal模式
            const animState = this.animationComponent.getState(this.currentAnimationName);
            if (animState) {
                animState.wrapMode = AnimationClip.WrapMode.Normal;
            }

            // 平滑停止动画：不立即停止，而是让当前循环完成
            setTimeout(() => {
                // 检查节点和组件是否仍然有效
                if (this.targetNode && this.targetNode.isValid && 
                    this.animationComponent && !this.isMoving) {
                    this.animationComponent.stop();
                }
            }, 50); // 延迟50ms停止，让当前帧完成

            this.currentAnimationName = null;
        }
    }

    /**
     * 播放攻击动画
     * @param direction 攻击方向，如果不提供则播放默认攻击动画
     * @param targetPos 攻击目标位置，用于弓箭手射箭动画
     */
    public playAttackAnimation(direction?: MoveDirection, targetPos?: {x: number, y: number}): void {
        // 根据方向生成攻击动画名称
        let animationName = this.getAttackDirectionIndex(direction);
        this.playAnimation(animationName);

        // 如果是弓箭手且提供了目标位置，播放射箭动画
        if (this.uType === UnitType.archer && targetPos) {
            // 判断targetPos是否与自己相邻（x或y坐标差值的绝对值为1）
            const deltaX = Math.abs(targetPos.x - this.tiledObject.data.position.x);
            const deltaY = Math.abs(targetPos.y - this.tiledObject.data.position.y);
            if (deltaX === 1 || deltaY === 1) {
                this.playArrowAnimation(targetPos);   //直射
            }else{
                this.playParabolicAttackAnimation(targetPos,'arrow'); //抛射
            }
        }
        // 如果是防御塔且提供了目标位置，播放火球动画
        if (this.entityType === EntityType.building && targetPos) {
            //this.playFireballAnimation(targetPos);
            //TODO 发射火球动画
            this.playParabolicAttackAnimation(targetPos);
        }
    }

    /**
     * 播放死亡动画
     * @param entityType 实体类型，用于区分单位和建筑的死亡动画，默认为单位
     */
    public playDeathAnimation(): void {
        let uType = ResourceLoadManager.getUnitPrefixType(this.uType);
        let cType = ResourceLoadManager.getCTypeforPlayer(this.playerType);

        // 根据实体类型生成不同的死亡动画名称
        let animationName: string;
        if (this.entityType === EntityType.building) {
            uType = ResourceLoadManager.getBuildingTypePath(this.uType);
            // 建筑死亡动画
            animationName = `building_death`;
        } else {
            // 单位死亡动画（默认）
            animationName = `${uType}_${cType}_death`;
        }

        this.playAnimation(animationName, 2.0, () => {
            // 死亡动画播放完成后，移除节点
            if (this.tiledObject && this.tiledObject.data.entityType != EntityType.building) {
               this.tiledObject.node.destroy();
            }
        });
    }

    /**
     * 播放指定名称的动画
     * @param animationName 动画名称
     * @param speed 播放速度，默认为2倍速
     */
    public playAnimation(animationName: string, speed: number = 2.0, callback?: () => void): void {
        if (!this.animationComponent) {
            LOG.warn('TiledObjectAnimationManager: 动画组件未初始化');
            return;
        }

        const clips = this.animationComponent.clips;
        const targetClip = clips.find(clip => clip.name === animationName);

        if (!targetClip) {
            LOG.warn(`TiledObjectAnimationManager: 找不到名为 ${animationName} 的动画剪辑`);
            return;
        }

        // 如果当前已经在播放这个动画，则不重复播放
        if (this.currentAnimationName === animationName && this.animationComponent.getState(animationName)?.isPlaying) {
            return;
        }

        // 平滑切换：如果有当前动画在播放，先停止它
        if (this.currentAnimationName && this.currentAnimationName !== animationName) {
            const currentState = this.animationComponent.getState(this.currentAnimationName);
            if (currentState) {
                currentState.wrapMode = AnimationClip.WrapMode.Normal;
            }
            this.animationComponent.stop();
        }

        // 播放指定动画
        this.currentAnimationName = animationName;
        // 设置播放速度
        const animState = this.animationComponent.getState(animationName);
        if (animState) {
            animState.speed = speed;
        }

        // 播放完成后调用回调函数
        if (callback) {
            this.animationComponent.on(Animation.EventType.FINISHED, (type, state)=>{
                callback();
            },this.animationComponent); 
        }
        this.animationComponent.play(animationName);
    }

    /**
     * 播放受伤动画
     * 半透明红色闪烁效果和飘字动画
     * @param damageValue 受伤数值，用于飘字显示
     */
    public playDamageAnimation(damageValue?: number): void {
        if (this.injuredTween) {
            return;
        }
        const spriteComponent = this.targetNode.getComponent(Sprite);
        if (!spriteComponent) return;
        const originalColor = Color.WHITE;
        // 受伤颜色：半透明红色
        const damageColor = new Color(255, 255, 255, 128);

        // 创建闪烁动画：原色 -> 红色 -> 原色 -> 红色 -> 原色，持续1秒
        this.injuredTween = tween(spriteComponent)
            .to(0.1, { color: damageColor })   // 0.1秒变为红色
            .to(0.1, { color: originalColor }) // 0.1秒恢复原色
            .to(0.1, { color: damageColor })   // 0.1秒变为红色
            .to(0.1, { color: originalColor }) // 0.1秒恢复原色
            .to(0.1, { color: damageColor })   // 0.1秒变为红色
            .to(0.1, { color: originalColor }) // 0.1秒恢复原色
            .call(() => {
                // 只有在节点有效时才设置颜色
                if (this.targetNode && this.targetNode.isValid) {
                    this.setSpriteColorWhite();
                }
                this.injuredTween = null;
            })
            .start();

        // 播放受伤飘字动画
        if (damageValue !== undefined && damageValue > 0) {
            this.playFloatingTextAnimation(`-${damageValue}`, new Color(255, 0, 0, 255)); // 红色文字
        }
    }

    /**
     * 播放治疗动画
     * 绿色闪烁效果和飘字动画
     * @param healValue 治疗数值，用于飘字显示
     */
    public playHealAnimation(healValue?: number): void {
        let effectNode = this.targetNode.getChildByName("effect");
        effectNode.active = true;
        let effectAnimation = effectNode.getComponent(Animation);
        if(effectAnimation){
            const clips = effectAnimation.clips;
            const targetClip = clips.find(clip => clip.name === "therapy");
            if (!targetClip) {
                LOG.warn(`TiledObjectAnimationManager: 找不到名为 therapy 的动画剪辑`);
                return;
            }
            effectAnimation.play(targetClip.name);
            //TODO 播放完成后隐藏动画节点
            effectAnimation.once(Animation.EventType.FINISHED, () => {
                let effectSprite = effectNode.getComponent(Sprite);
                effectSprite.spriteFrame = null;
                effectNode.active = false;
            });
        }

        // 播放治疗飘字动画
        if (healValue !== undefined && healValue > 0) {
            this.playFloatingTextAnimation(`+${healValue}`, new Color(0, 255, 0, 255)); // 绿色文字
        }
    }

    /**
     * 播放击杀奖励动画
     * 显示击杀敌方后获得的经济奖励飘字动画
     * @param awardValue 奖励数值，用于飘字显示
     */
    public playKilledAwardAnimation(awardValue: number): void {
        // 播放击杀奖励飘字动画
        if (awardValue > 0) {
            this.playFloatingTextAnimation("💎+"+awardValue, Color.YELLOW);
        }
    }

    /**
     * 播放创建动画
     */
    public playCreateAnimation(): void {
        let effectNode = this.targetNode.getChildByName("effect");
        effectNode.active = true;
        let effectAnimation = effectNode.getComponent(Animation);
        if(effectAnimation){
            const clips = effectAnimation.clips;
            const targetClip = clips.find(clip => clip.name === "creater");
            if (!targetClip) {
                LOG.warn(`TiledObjectAnimationManager: 找不到名为 creater 的动画剪辑`);
                return;
            }
            // 播放动画并设置为循环播放
            let state = effectAnimation.play(targetClip.name);
            //TODO 播放完成后隐藏动画节点
            effectAnimation.once(Animation.EventType.FINISHED, () => {
                LOG.log(`TiledObjectAnimationManager: 播放创建动画完成`);
                let effectSprite = effectNode.getComponent(Sprite);
                effectSprite.spriteFrame = null;
                effectNode.active = false;
            });
        }
    }

    /**播放被采集动画
     * 设置动画为循环播放模式
     */
    public playCollectAnimation():void{
        let effectNode = this.targetNode.getChildByName("effect");
        effectNode.active = true;
        let tarns = effectNode.getComponent(UITransform);
        tarns.setContentSize(32,32)
        let animation = effectNode.getComponent(Animation);
        if(animation){
            const clips = animation.clips;
            const targetClip = clips.find(clip => clip.name === "collect");
            if (!targetClip) {
                LOG.warn(`TiledObjectAnimationManager: 找不到名为 collect 的动画剪辑`);
                return;
            }
            // 延时播放动画
            setTimeout(() => {
                // 检查节点是否仍然有效
                if (this.targetNode && this.targetNode.isValid && animation) {
                    animation.play(targetClip.name);
                    animation.on(Animation.EventType.PLAY, () => {
                        LOG.log(`TiledObjectAnimationManager: 播放被采集动画完成`);
                        // 获取动画状态并确保循环播放
                        const animState = animation.getState(targetClip.name);
                        if (animState) {
                            animState.wrapMode = AnimationClip.WrapMode.Loop;
                            LOG.log(`TiledObjectAnimationManager: collect 动画已设置为循环播放`);
                        }
                    })
                }
            }, 1000);
        }
    }

    /**
     * 播放飘字动画
     * 创建文字节点并实现向上飘动的动画效果
     * @param text 要显示的文字内容
     * @param color 文字颜色
     * @param duration 动画持续时间，默认1.5秒
     * @param floatDistance 飘动距离，默认30像素
     */
    public playFloatingTextAnimation(
        text: string,
        color: Color,
        duration: number = 1.5,
        floatDistance: number = 30
    ): void {
        if (!this.targetNode || !this.targetNode.isValid) {
            LOG.warn('TiledObjectAnimationManager: 目标节点无效，无法播放飘字动画');
            return;
        }

        // 停止之前的飘字动画
        this.stopFloatingTextAnimation();

        // 创建飘字节点
        this.floatingTextNode = this.createFloatingTextNode(text, color);
        if (!this.floatingTextNode) {
            LOG.warn('TiledObjectAnimationManager: 无法创建飘字节点');
            return;
        }

        // 将飘字节点添加到目标节点的父节点（地图节点）
        const mapNode = this.targetNode.parent;
        if (!mapNode) {
            LOG.warn('TiledObjectAnimationManager: 无法获取地图节点');
            this.floatingTextNode.destroy();
            this.floatingTextNode = null;
            return;
        }
        mapNode.addChild(this.floatingTextNode);

        // 设置飘字起始位置（目标节点上方）
        const startPos = this.targetNode.position.clone();
        startPos.y += 20; // 在目标上方20像素开始
        this.floatingTextNode.setPosition(startPos);

        // 计算目标位置（向上飘动）
        const targetPos = startPos.clone();
        targetPos.y += floatDistance;

        // 创建飘字动画：向上移动 + 淡出效果
        const transform = this.floatingTextNode.getComponent(UITransform);
        const label = this.floatingTextNode.getComponent(Label);

        if (transform && label) {
            // 设置初始透明度
            const initialColor = label.color.clone();
            const fadeColor = initialColor.clone();
            fadeColor.a = 0; // 完全透明

            this.floatingTextTween = tween(this.floatingTextNode)
                .parallel(
                    // 位置动画：向上飘动
                    tween(this.floatingTextNode).to(duration, { position: targetPos }, { easing: 'sineOut' }),
                    // 透明度动画：延迟0.5秒后开始淡出
                    tween(label).delay(duration * 0.3).to(duration * 0.7, { color: fadeColor }, { easing: 'sineIn' })
                )
                .call(() => {
                    // 动画完成后销毁飘字节点
                    if (this.floatingTextNode && this.floatingTextNode.isValid) {
                        this.floatingTextNode.destroy();
                    }
                    this.floatingTextNode = null;
                    this.floatingTextTween = null;
                })
                .start();
        }
    }

    /**
     * 创建飘字节点
     * @param text 文字内容
     * @param color 文字颜色
     * @returns 飘字节点，如果创建失败返回null
     */
    private createFloatingTextNode(text: string, color: Color): Node | null {
        const textNode = new Node('FloatingText');

        // 添加Label组件
        const label = textNode.addComponent(Label);
        label.string = text;
        label.fontSize = 14;
        label.color = color;
        label.horizontalAlign = Label.HorizontalAlign.CENTER;
        label.verticalAlign = Label.VerticalAlign.CENTER;

        // 添加UITransform组件
        const transform = textNode.addComponent(UITransform);
        transform.setContentSize(60, 20); // 设置合适的大小
        transform.setAnchorPoint(0.5, 0.5); // 居中锚点

        return textNode;
    }

    /**
     * 停止飘字动画
     */
    public stopFloatingTextAnimation(): void {
        if (this.floatingTextTween) {
            this.floatingTextTween.stop();
            this.floatingTextTween = null;
        }

        if (this.floatingTextNode && this.floatingTextNode.isValid) {
            this.floatingTextNode.destroy();
            this.floatingTextNode = null;
        }
    }

    /**
     * 播放射箭动画
     * 创建箭矢节点并实现从弓箭手位置到目标位置的飞行动画
     * @param targetPos 目标位置（网格坐标）
     */
    public playArrowAnimation(targetPos: {x: number, y: number}): void {
        if (!this.targetNode || !this.targetNode.isValid) {
            LOG.warn('TiledObjectAnimationManager: 目标节点无效，无法播放射箭动画');
            return;
        }

        // 停止之前的箭矢动画
        this.stopArrowAnimation();

        // 创建箭矢节点
        this.arrowNode = this.createArrowNode();
        if (!this.arrowNode) {
            LOG.warn('TiledObjectAnimationManager: 无法创建箭矢节点');
            return;
        }

        // 将箭矢添加到弓箭手的父节点（地图节点）
        const mapNode = this.targetNode.parent;
        if (!mapNode) {
            LOG.warn('TiledObjectAnimationManager: 无法获取地图节点');
            this.arrowNode.destroy();
            this.arrowNode = null;
            return;
        }
        mapNode.addChild(this.arrowNode);

        // 设置箭矢起始位置（弓箭手位置）
        const startPos = this.targetNode.position.clone();
        this.arrowNode.setPosition(startPos);

        // 计算目标世界坐标
        const targetWorldPos = this.gridToWorldPosition(targetPos.x, targetPos.y);

        // 计算箭矢飞行方向并旋转箭矢
        this.rotateArrowToTarget(this.arrowNode, startPos, targetWorldPos);

        // 创建箭矢飞行动画
        const flightDuration = 0.3; // 飞行时间0.3秒
        this.arrowTween = tween(this.arrowNode)
            .to(flightDuration, { position: targetWorldPos }, { easing: 'sineOut' })
            .call(() => {
                // 箭矢到达目标后销毁
                if (this.arrowNode && this.arrowNode.isValid) {
                    this.arrowNode.destroy();
                }
                this.arrowNode = null;
                this.arrowTween = null;
            })
            .start();
    }

    /**
     * 创建箭矢节点
     * @returns 箭矢节点，如果创建失败返回null
     */
    private createArrowNode(): Node | null {
        const arrowNode = new Node('Arrow');

        // 添加Sprite组件
        const sprite = arrowNode.addComponent(Sprite);

        // 添加UITransform组件
        const transform = arrowNode.addComponent(UITransform);
        // 尝试加载箭矢精灵帧
        this.loadArrowSpriteFrame(sprite);
        transform.setContentSize(8, 4); // 箭矢大小：长8像素，宽4像素
        transform.setAnchorPoint(0, 0.5); // 锚点设置在左中，便于旋转

        return arrowNode;
    }

    /**
     * 加载箭矢精灵帧
     * @param sprite 精灵组件
     */
    private loadArrowSpriteFrame(sprite: Sprite): void {
        // 尝试从UI资源中加载箭头图片
        sprite.spriteFrame = ResourceLoadManager.getUIPanelSpriteFrame('arrowBeige_right');
        sprite.sizeMode = Sprite.SizeMode.CUSTOM;
        sprite.type = Sprite.Type.SIMPLE;
        sprite.trim = true;
    }

    /**
     * 根据目标方向旋转箭矢
     * @param arrowNode 箭矢节点
     * @param startPos 起始位置
     * @param targetPos 目标位置
     */
    private rotateArrowToTarget(arrowNode: Node, startPos: Vec3, targetPos: Vec3): void {
        const deltaX = targetPos.x - startPos.x;
        const deltaY = targetPos.y - startPos.y;

        // 计算角度（弧度转角度）
        const angle = Math.atan2(deltaY, deltaX) * (180 / Math.PI);

        // 设置箭矢旋转角度
        arrowNode.setRotationFromEuler(0, 0, angle);
    }

    /**
     * 将网格坐标转换为世界坐标
     * @param gridX 网格X坐标
     * @param gridY 网格Y坐标
     * @returns 世界坐标
     */
    private gridToWorldPosition(gridX: number, gridY: number): Vec3 {
        // 每个格子的像素大小为16x16
        const tilePixelSize = 16;

        // 计算格子中心点的像素坐标（以左下角为原点）
        const pixelX = gridX * tilePixelSize + tilePixelSize / 2;
        const pixelY = gridY * tilePixelSize + tilePixelSize / 2;

        // 转换为以地图中心为原点的坐标
        const worldX = pixelX - 400;
        const worldY = 400 - pixelY;

        return new Vec3(worldX, worldY, 0);
    }

    /**
     * 播放抛物线攻击动画
     * @param targetPos 目标网格坐标
     * @param projectileType 抛射物类型，默认为'stone'（石头）
     * @param arcHeight 抛物线高度，默认为30像素
     * @param duration 飞行时间，默认为0.6秒
     */
    public playParabolicAttackAnimation(
        targetPos: {x: number, y: number},
        projectileType: string = 'stone',
        arcHeight: number = 30,
        duration: number = 0.6
    ): void {
        if (!this.targetNode || !this.targetNode.isValid) {
            LOG.warn('TiledObjectAnimationManager: 目标节点无效，无法播放抛物线攻击动画');
            return;
        }

        // 停止之前的抛物线攻击动画
        this.stopParabolicAttackAnimation();
        let isBoom:boolean = false;
        // 创建抛射物节点
        if(projectileType == 'stone'){
            this.arrowNode = this.createProjectileNode(projectileType);
            isBoom = true;
        }else if(projectileType == 'arrow'){
            this.arrowNode = this.createArrowNode();
        }
        if (!this.arrowNode) {
            LOG.warn('TiledObjectAnimationManager: 无法创建抛射物节点');
            return;
        }

        // 将抛射物添加到攻击者的父节点（地图节点）
        const mapNode = this.targetNode.parent;
        if (!mapNode) {
            LOG.warn('TiledObjectAnimationManager: 无法获取地图节点');
            this.arrowNode.destroy();
            this.arrowNode = null;
            return;
        }
        mapNode.addChild(this.arrowNode);

        // 设置抛射物起始位置（攻击者位置）
        const startPos = this.targetNode.position.clone();
        this.arrowNode.setPosition(new Vec3(startPos.x,startPos.y+6,0));

        // 计算目标世界坐标
        const targetWorldPos = this.gridToWorldPosition(targetPos.x, targetPos.y);
        if(projectileType == 'arrow'){
            // 计算箭矢飞行方向并旋转箭矢
            this.rotateArrowToTarget(this.arrowNode, startPos, targetWorldPos);
        }
        

        // 计算抛物线路径的中间点（最高点）
        const midX = (startPos.x + targetWorldPos.x) / 2;
        const midY = Math.max(startPos.y, targetWorldPos.y) + arcHeight;
        const midPos = new Vec3(midX, midY, 0);

        // 创建抛物线飞行动画序列
        // 第一段：从起点到最高点
        const firstHalfDuration = duration * 0.2;
        const firstTween = tween(this.arrowNode)
            .to(firstHalfDuration, { position: midPos }, { easing: 'sineOut' });
        
        // 第二段：从最高点到目标点
        const secondHalfDuration = duration * 0.2;
        const secondTween = tween(this.arrowNode)
            .to(secondHalfDuration, { position: targetWorldPos }, { easing: 'sineIn' })
            .call(() => {
                if(isBoom){
                    //播放爆炸动画,动画播放结束再销毁
                    let anima = this.arrowNode.getComponent(Animation)
                    let targetClip = anima.clips.find(clip => clip.name === "boom");
                    if (targetClip) {
                        targetClip.speed = 2
                        anima.play(targetClip.name)
                        anima.once(Animation.EventType.FINISHED, () => {
                            if (this.arrowNode && this.arrowNode.isValid) {
                                this.arrowNode.destroy();
                            }
                            this.arrowNode = null;
                            this.arrowTween = null;
                            LOG.log('TiledObjectAnimationManager: 抛物线攻击动画完成');
                        })
                    }else{
                        LOG.error('TiledObjectAnimationManager: 找不到名为 boom 的动画剪辑');
                    }
                }else{
                    // 销毁箭头
                    if (this.arrowNode && this.arrowNode.isValid) {
                        this.arrowNode.destroy();
                    }
                    this.arrowNode = null;
                    this.arrowTween = null;
                }
                
                
            });

        // 连接两段动画
        this.arrowTween = firstTween.then(secondTween).start();
    }

    /**
     * 创建抛射物节点
     * @param projectileType 抛射物类型
     * @returns 抛射物节点，如果创建失败返回null
     */
    private createProjectileNode(projectileType: string): Node | null {
        if (!this.tiledObject.bulletPrefab) {
            LOG.warn('TiledObjectAnimationManager: 子弹预制体未加载');
            return null;
        }
        const projectileNode = instantiate(this.tiledObject.bulletPrefab);
        if (!projectileNode) {
            LOG.warn('TiledObjectAnimationManager: 无法实例化子弹预制体');
            return null;
        }


        // 获取Sprite组件
        const sprite = projectileNode.getComponent(Sprite);
        // 获取UITransform组件
        const transform = projectileNode.getComponent(UITransform);

        // 根据抛射物类型加载不同的精灵帧
        this.loadProjectileSpriteFrame(sprite);

        // 设置抛射物大小
        const size = this.getProjectileSize(projectileType);
        transform.setContentSize(40, 36);
        transform.setAnchorPoint(0.5, 0.5); // 锚点设置在中心

        return projectileNode;
    }

    /**
     * 加载抛射物精灵帧
     * @param sprite 精灵组件
     * @param projectileType 抛射物类型
     */
    private loadProjectileSpriteFrame(sprite: Sprite): void {
        // 尝试从UI资源中加载抛射物图片
        sprite.spriteFrame = ResourceLoadManager.getSpriteFrameForAtlasPath(SpriteAtlasPath.uiBoom, "boom_1");

        //sprite.color = Color.BLACK;
        sprite.sizeMode = Sprite.SizeMode.CUSTOM;
        sprite.type = Sprite.Type.SIMPLE;
        sprite.trim = true;
    }

    /**
     * 获取抛射物大小
     * @param projectileType 抛射物类型
     * @returns 抛射物尺寸
     */
    private getProjectileSize(projectileType: string): {width: number, height: number} {
        switch (projectileType) {
            case 'stone':
                return {width: 12, height: 12};
            case 'fireball':
                return {width: 16, height: 16};
            case 'ice':
                return {width: 14, height: 14};
            default:
                return {width: 12, height: 12};
        }
    }

    /**
     * 停止抛物线攻击动画
     */
    public stopParabolicAttackAnimation(): void {
        if (this.arrowTween) {
            this.arrowTween.stop();
            this.arrowTween = null;
        }

        // 销毁抛射物节点
        if (this.arrowNode && this.arrowNode.isValid) {
            this.arrowNode.destroy();
            this.arrowNode = null;
            LOG.log('TiledObjectAnimationManager: 抛射物节点已销毁');
        }
    }

    /**
     * 停止箭矢飞行动画
     */
    public stopArrowAnimation(): void {
        if (this.arrowTween) {
            this.arrowTween.stop();
            this.arrowTween = null;
        }

        // 销毁箭矢节点
        if (this.arrowNode && this.arrowNode.isValid) {
            this.arrowNode.destroy();
            this.arrowNode = null;
            LOG.log('TiledObjectAnimationManager: 箭矢节点已销毁');
        }
    }

    /**
     * 执行节点移动动画（使用tween实现）
     * @param node 要移动的节点
     * @param targetPos 目标位置
     * @param onComplete 完成回调
     */
    public animateNodeMovement(node: Node, targetPos: Vec3, onComplete?: () => void): void {
        // 检查节点是否有效
        if (!node || !node.isValid) {
            LOG.warn('TiledObjectAnimationManager: 尝试对无效节点执行动画');
            return;
        }

        // 计算移动方向
        const currentPos = { x: node.position.x, y: node.position.y };
        const targetGridPos = { x: targetPos.x, y: targetPos.y };
        const moveDirection = this.calculateMoveDirection(currentPos, targetGridPos);

        // 设置移动状态
        this.isMoving = true;

        // 计算目标动画名称
        let targetAnimationName: string | null = null;
        if (moveDirection && this.animationComponent && this.animationComponent.clips.length > 0) {
            targetAnimationName = this.getDirectionIndex(moveDirection);
        }

        // 只有在目标动画与当前播放的动画不同时才切换
        const shouldPlayAnimation = !this.currentAnimationName ||
            (targetAnimationName && this.currentAnimationName !== targetAnimationName);

        if (shouldPlayAnimation && moveDirection && targetAnimationName) {
            this.currentDirection = moveDirection;
            // 避免重复播放相同动画
            if (this.lastPlayedAnimationName === targetAnimationName &&
                this.animationComponent.getState(targetAnimationName)?.isPlaying) {
                return; // 如果相同动画正在播放，直接返回
            }

            // 使用防抖机制避免频繁切换动画
            if (this.animationSwitchTimer !== null) {
                clearTimeout(this.animationSwitchTimer);
            }
            this.animationSwitchTimer = setTimeout(() => {
                // 检查节点和动画管理器是否仍然有效
                if (this.targetNode && this.targetNode.isValid && 
                    this.animationComponent && this.animationComponent.isValid) {
                    this.playMoveAnimation(moveDirection);
                    this.lastPlayedAnimationName = targetAnimationName;
                }
                this.animationSwitchTimer = null;
            }, 16); // 一帧的时间，约16ms
        } else if (!this.currentAnimationName) {
            this.playMoveAnimation();
        }

        // 停止当前的tween动画
        this.stopMoveTween();

        const duration = 0.5; // 动画持续时间（秒）

        // 使用tween创建移动动画
        this.moveTween = tween(node)
            .to(duration, { position: targetPos }, { easing: 'sineInOut' })
            .call(() => {
                // 动画完成回调
                this.moveTween = null;
                this.isMoving = false;

                // 延迟一小段时间后停止移动动画，避免频繁切换
                setTimeout(() => {
                    // 检查节点是否仍然有效
                    if (this.targetNode && this.targetNode.isValid && !this.isMoving) {
                        this.stopMoveAnimation();
                    }
                }, 100);

                // 执行完成回调
                if (onComplete) {
                    onComplete();
                }
            })
            .start();
    }

    /** 
     * 停止播放特效
    */
    public stopEffect():void{
        let effectNode = this.targetNode.getChildByName("effect");
        if(effectNode && effectNode.active){
            let animation = effectNode.getComponent(Animation);
            if(animation){
                animation.pause();
            }
            effectNode.active = false
        }
    }

    /**
     * 停止当前的tween动画
     */
    public stopMoveTween(): void {
        if (this.moveTween) {
            this.moveTween.stop();
            this.moveTween = null;
        }
    }

    /**
     * 停止所有动画
     */
    public stopAllAnimations(): void {
        if (!this.animationComponent) {
            return;
        }

        // 重置所有动画的循环播放状态为Normal模式
        const clips = this.animationComponent.clips;
        clips.forEach(clip => {
            if (clip && clip.name) {
                const animState = this.animationComponent.getState(clip.name);
                if (animState) {
                    animState.wrapMode = AnimationClip.WrapMode.Normal;
                }
            }
        });

        this.animationComponent.stop();
        this.currentAnimationName = null;

        // 停止tween动画，防止位置冲突
        this.stopMoveTween();

        // 停止受伤/治疗动画
        if (this.injuredTween) {
            this.injuredTween.stop();
            this.injuredTween = null;
            // 只有在节点有效时才设置颜色
            if (this.targetNode && this.targetNode.isValid) {
                this.setSpriteColorWhite();
            }
        }

    
        // 停止箭矢飞行动画
        this.stopArrowAnimation();

        // 停止抛物线攻击动画
        this.stopParabolicAttackAnimation();

        // 清除动画切换定时器
        if (this.animationSwitchTimer !== null) {
            clearTimeout(this.animationSwitchTimer);
            this.animationSwitchTimer = null;
        }

        // 重置移动状态
        this.isMoving = false;
    }

    /**
     * 暂停所有动画播放
     * 包括Animation组件动画和Tween动画
     */
    public pauseAllAnimations(): void {
        // 暂停Animation组件动画
        if (this.animationComponent && this.currentAnimationName) {
            const animState = this.animationComponent.getState(this.currentAnimationName);
            if (animState && animState.isPlaying) {
                this.animationComponent.pause();
            }
        }

        // 暂停Tween动画
        if (this.moveTween) {
            this.moveTween.pause();
        }
        if (this.injuredTween) {
            this.injuredTween.pause();
            // 只有在节点有效时才设置颜色
            if (this.targetNode && this.targetNode.isValid) {
                this.setSpriteColorWhite();
            }
        }

        let effectNode = this.targetNode.getChildByName("effect");
        if(effectNode.active){
            let animation = effectNode.getComponent(Animation);
            if(animation){
                animation.pause();
            }
            effectNode.active = false
        }

        // 暂停并销毁弓箭手的箭矢动画和节点
        this.stopArrowAnimation();

        // 暂停并销毁抛物线攻击动画和节点
        this.stopParabolicAttackAnimation();

        // 清除动画切换定时器
        if (this.animationSwitchTimer !== null) {
            clearTimeout(this.animationSwitchTimer);
            this.animationSwitchTimer = null;
        }
    }

    /**
     * 恢复所有动画播放
     * 包括Animation组件动画和Tween动画
     */
    public resumeAllAnimations(): void {
        // 恢复Animation组件动画
        if (this.animationComponent && this.currentAnimationName) {
            const animState = this.animationComponent.getState(this.currentAnimationName);
            if (animState && !animState.isPlaying) {
                this.animationComponent.resume();
            }
        }

        // 恢复Tween动画
        if (this.moveTween) {
            this.moveTween.resume();
        }
    }


    /**
     * 计算移动方向
     * @param fromPos 起始位置
     * @param toPos 目标位置
     * @returns 移动方向，如果没有移动则返回null
     */
    private calculateMoveDirection(fromPos: {x: number, y: number}, toPos: {x: number, y: number}): MoveDirection | null {
        const deltaX = toPos.x - fromPos.x;
        const deltaY = toPos.y - fromPos.y;

        // 如果没有移动，返回null
        if (deltaX === 0 && deltaY === 0) {
            return null;
        }

        // 优先判断主要移动方向
        if (Math.abs(deltaX) > Math.abs(deltaY)) {
            return deltaX > 0 ? MoveDirection.RIGHT : MoveDirection.LEFT;
        } else {
            return deltaY > 0 ? MoveDirection.UP : MoveDirection.DOWN;
        }
    }

    /**
     * 计算攻击方向
     * 根据攻击者位置和目标位置计算攻击应该面向的方向
     * @param attackerPos 攻击者位置
     * @param targetPos 目标位置
     * @returns 攻击方向，如果位置相同则返回默认方向DOWN
     */
    public calculateAttackDirection(attackerPos: {x: number, y: number}, targetPos: {x: number, y: number}): MoveDirection {
        const deltaX = targetPos.x - attackerPos.x;
        const deltaY = targetPos.y - attackerPos.y;

        // 如果位置相同，返回默认方向
        if (deltaX === 0 && deltaY === 0) {
            return MoveDirection.DOWN;
        }

        // 根据绝对值较大的方向来确定主要攻击方向
        if (Math.abs(deltaX) > Math.abs(deltaY)) {
            // 水平方向为主
            return deltaX > 0 ? MoveDirection.RIGHT : MoveDirection.LEFT;
        } else {
            // 垂直方向为主
            return deltaY > 0 ? MoveDirection.DOWN : MoveDirection.UP;
        }
    }

    /**
     * 获取移动方向对应的动画索引
     * 动画顺序：0-down, 1-left, 2-right, 3-up
     * @param direction 移动方向
     * @returns 动画索引
     */
    private getDirectionIndex(direction: MoveDirection): string {
        let animName = ResourceLoadManager.getUnitPrefixType(this.uType);
        let cType = ResourceLoadManager.getCTypeforPlayer(this.playerType);
        return `${animName}_${cType}_move_${direction}`;
    }

    /**
     * 获取攻击方向对应的动画索引
     * @param direction 攻击方向
     * @returns 攻击动画索引
     */
    private getAttackDirectionIndex(direction: MoveDirection): string {
        let animName = ResourceLoadManager.getUnitPrefixType(this.uType);
        let cType = ResourceLoadManager.getCTypeforPlayer(this.playerType);
        let result = `${animName}_${cType}_attack_${direction}`;
        if (this.entityType === EntityType.building) {
            animName = ResourceLoadManager.getBuildingTypePath(this.uType);
            //TODO 防御塔攻击动画
            result = `${animName}_attack`;
        }
        LOG.log(`生成攻击动画名称: ${result} (单位类型: ${this.uType}, 玩家类型: ${this.playerType}, 方向: ${direction})`);
        return result;
    }

    /**
     * 图片颜色设置为白色
     */
    public setSpriteColorWhite(): void {
        if(!this.targetNode) return;
        const sprite = this.targetNode.getComponent(Sprite);
        if (sprite && sprite.color) {
            sprite.color = Color.WHITE;
        }
    }

    /**
     * 清理资源
     */
    public destroy(): void {
        try {
            // 清除动画切换定时器
            if (this.animationSwitchTimer !== null) {
                clearTimeout(this.animationSwitchTimer);
                this.animationSwitchTimer = null;
            }
            
            // 停止所有效果和动画
            this.stopEffect();
            this.stopAllAnimations();
            this.stopMoveTween();

            // 停止受伤/治疗动画
            if (this.injuredTween) {
                this.injuredTween.stop();
                this.injuredTween = null;
            }

            // 停止飘字动画
            this.stopFloatingTextAnimation();

            // 清理所有引用
            this.animationComponent = null;
            this.currentAnimationName = null;
            this.lastPlayedAnimationName = null;
            this.moveTween = null;
            this.arrowTween = null;
            this.arrowNode = null;
            this.floatingTextTween = null;
            this.floatingTextNode = null;
            this.tiledObject = null;
            this.targetNode = null;
        } catch (error) {
            LOG.error('TiledObjectAnimationManager: 销毁过程中发生错误:', error);
        }
    }

    /**
     * 清理函数清理数据跟动画
     */
    public clear(): void {
        this.stopAllAnimations();
        this.stopMoveTween();
        this.stopFloatingTextAnimation();
        if (this.animationComponent) {
            this.animationComponent.stop();
        }
        this.currentAnimationName = null;
        this.lastPlayedAnimationName = null;
        this.moveTween = null;
    }
}